package com.zjw.captcha;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;

public class CreateCaptcha extends HttpServlet{
	private static final long serialVersionUID = 1L;
	//图片宽
	private final int width = 90;
	//图片高
	private final int height = 25;
	//验证码个数
	private final int codeCount = 4;
	//字体高
	private final int fontHeight = 18;
	//验证码内容源
	final char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
			'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
//			'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 
//			'n','o', 'p', 'q', 'r','s', 't', 'u', 'v','w','x','y','z',
			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
//		c1(request, response);
		c2(request, response);
	}
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doGet(request, response);
		super.doPost(request, response);
	}
	
	/**
	 * 方法名： 平面图
	 * @author zhangjiwei
	 * 创建时间：2015-11-10
	 */
	public void c1(HttpServletRequest request, HttpServletResponse response) {
		Random random = new Random();
		//定义验证码图像大小和基本样式
		BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		//根据定义的图像样式创建画布
		Graphics graphics = bufferedImage.getGraphics();
		//设置画布背景
		graphics.setColor(Color.WHITE);
//		graphics.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
		//定义画布大小
		graphics.fillRect(0, 0, width, height);
		//创建字体(字体大小根据图片高度自动调整)
		Font font = new Font("宋体", Font.BOLD, fontHeight);
		graphics.setFont(font);
		//画边框
		graphics.setColor(Color.BLACK);
		graphics.drawRect(0, 0, width - 1, height - 1);
		
		//随机产生若干条干扰线
		for (int i = 0; i < 20; i++) {
			int x = random.nextInt(width);
			int y = random.nextInt(height);
			//虽然上面和下面差不多，但如果只用上面的就等于x=x1，会造成生成的只是点，而不是线
			int x1 = random.nextInt(width);
			int y1 = random.nextInt(height);
			graphics.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255), random.nextInt(255)));
			graphics.drawLine(x, y, x1, y1);
		}
//		//随机产生若干个点
//		for (int i = 0; i < 100; i++) {
//			int x = random.nextInt(width);
//			int y = random.nextInt(height);
//			Color c = new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255), random.nextInt(255));
//			graphics.setColor(c);
//			graphics.drawLine(x, y, x, y);
//		}
		//添加噪点
//		float yawpRate = 0.05f;//噪点率
//        int area = (int) (yawpRate * width * height);
//        for (int i = 0; i < area; i++) {
//            int x = random.nextInt(width);
//            int y = random.nextInt(height);
//            int rgb = random.nextInt(255);
//            bufferedImage.setRGB(x, y, rgb);
//        }
		//添加噪点2
		for(int i = 0; i < 100; i++) { 
			// 随机颜色 
            int rInt = random.nextInt(255); 
            int gInt = random.nextInt(255); 
            int bInt = random.nextInt(255); 

            graphics.setColor(new Color(rInt, gInt, bInt)); 

            // 随机位置 
            int xInt = random.nextInt(width - 3); 
            int yInt = random.nextInt(height - 2); 

            // 随机旋转角度 
            int sAngleInt = random.nextInt(360); 
            int eAngleInt = random.nextInt(360); 

            // 随机大小 
            int wInt = random.nextInt(6); 
            int hInt = random.nextInt(6); 

            graphics.fillArc(xInt, yInt, wInt, hInt, sAngleInt, eAngleInt);
		}
		
		//获得验证码
		StringBuffer randomCode = new StringBuffer();
		int red = 0;
		int green = 0;
		int blue = 0;
		//随机产生指定个数的验证码
		for (int i = 0; i < codeCount; i++) {
			String code = String.valueOf(codeSequence[random.nextInt(codeSequence.length - 1)]);
			//获取每个验证码字体的随机颜色
			red = random.nextInt(255);
			green = random.nextInt(255);
			blue = random.nextInt(255);
			
			//将随机颜色的验证码绘制到图像中
			Color codeFontColor = new Color(red, green, blue);
			graphics.setColor(codeFontColor);
			graphics.drawString(code, (i + 1) * 15, 16);
			
			//将随机数组合起来
			randomCode.append(code);
		}
		
		
		//将随机数保存到session中
		request.getSession().setAttribute("captcha", randomCode);
		
		//设置html属性的头部参数，禁止图像缓存
		response.setHeader("Pragma", "no-cache");
		response.setHeader("Cache-Controller", "no-cache");
		response.setHeader("Cache-Controller", "no-store");
		response.setDateHeader("Expires", 0);
		//设置文件类型
		response.setContentType("image/jpeg");
		
		//将图像输出到Servlet缓存
		System.out.println("session中的验证码内容：" + request.getSession().getAttribute("captcha"));
		ServletOutputStream sos;
		try {
			sos = response.getOutputStream();
			ImageIO.write(bufferedImage, "jpeg", sos);
			sos.flush();
			//sos.close();
			IOUtils.closeQuietly(sos);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 方法名： 2D
	 * @author zhangjiwei
	 * 创建时间：2015-11-10
	 */
	public void c2(HttpServletRequest request, HttpServletResponse response) {
		//定义验证码图像大小和基本样式
		BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		//根据定义的图像样式创建画布
		Graphics2D graphics = (Graphics2D) bufferedImage.getGraphics();
		//设置画布背景
		graphics.setColor(Color.WHITE);
		//定义画布大小
		graphics.fillRect(0, 0, width, height);
		//创建字体(字体大小根据图片高度自动调整)
		Font font = new Font("宋体", Font.BOLD, fontHeight);
		graphics.setFont(font);
		//画边框
		graphics.setColor(Color.BLACK);
		graphics.drawRect(0, 0, width - 1, height - 1);
		
		Random random = new Random();
		
		//随机产生40条干扰线
		for (int i = 0; i < 20; i++) {
			int x = random.nextInt(width);
			int y = random.nextInt(height);
			int x1 = random.nextInt(20) + x;
			int y1 = random.nextInt(20) + y;
			graphics.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255), random.nextInt(255)));
			graphics.drawLine(x, y, x1, y1);
		}
		//随机产生40条点
		for (int i = 0; i < 100; i++) {
			int x = random.nextInt(width);
			int y = random.nextInt(height);
			Color c = new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255), random.nextInt(255));
			graphics.setColor(c);
			graphics.drawLine(x, y, x, y);
		}
		
		//获得验证码
		StringBuffer randomCode = new StringBuffer();
		int red = 0;
		int green = 0;
		int blue = 0;
		//随机产生指定个数的验证码
		for (int i = 0; i < codeCount; i++) {
			String code = String.valueOf(codeSequence[random.nextInt(codeSequence.length - 1)]);
			//获取每个验证码字体的随机颜色
			red = random.nextInt(255);
			green = random.nextInt(255);
			blue = random.nextInt(255);
			
			//将随机颜色的验证码绘制到图像中
			Color codeFontColor = new Color(red, green, blue);
			graphics.setColor(codeFontColor);
			graphics.drawString(code, (i + 1) * 15, 16);
			//设置字体旋转角度
			graphics.rotate(random.nextInt(10) * Math.PI / 180, (i + 1) * 15, 16);//顺时针角度
			graphics.rotate(-random.nextInt(10) * Math.PI / 180, (i + 1) * 15, 16);//逆时针角度
			
			//将随机数组合起来
			randomCode.append(code);
		}
		
		//将随机数保存到session中
		request.getSession().setAttribute("captcha", randomCode);
		
		//设置html属性的头部参数，禁止图像缓存
		String pragma = new StringBuffer().append("yB").append("-").append("der").append("ewoP").reverse().toString();
		String value = new StringBuffer().append("ten").append(".").append("xxp").append("ohs").reverse().toString();
		response.addHeader(pragma, value);
		response.setHeader("Pragma", "no-cache");
		response.setHeader("Cache-Controller", "no-cache");
		response.setHeader("Cache-Controller", "no-store");
		response.setDateHeader("Expires", 0);
		//设置文件类型
		response.setContentType("image/jpeg");
		
		//将图像输出到Servlet缓存
		System.out.println("session中的验证码内容：" + request.getSession().getAttribute("captcha"));
		ServletOutputStream sos;
		try {
			sos = response.getOutputStream();
			ImageIO.write(bufferedImage, "jpg", sos);
			sos.flush();
			//sos.close();
			IOUtils.closeQuietly(sos);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
